#include <wm_hal.h>
#include "py/compile.h"
#include "mod/machine.h"

#include "FreeRTOS.h"
#include "task.h"
#include "FreeRTOSConfig.h"

// systick
#define readl(addr) ({unsigned int __v = (*(volatile unsigned int *) (addr)); __v;})
__attribute__((isr)) void CORET_IRQHandler(void)
{
	readl(0xE000E010);
	HAL_IncTick();
    
#if (INCLUDE_xTaskGetSchedulerState == 1)
	if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
	{
#endif
	xPortSysTickHandler();
#if (INCLUDE_xTaskGetSchedulerState == 1)
	}
#endif
}

// uart0 interrupt
__attribute__((isr)) void UART0_IRQHandler(void)
{
#if MICROPY_HW_EN_UART0
    HAL_UART_IRQHandler(&MP_STATE_VM(pyb_uart_obj_all)[0]->huart);
#endif
}

// uart1 interrupt
__attribute__((isr)) void UART1_IRQHandler(void)
{
#if MICROPY_HW_EN_UART1
    HAL_UART_IRQHandler(&MP_STATE_VM(pyb_uart_obj_all)[1]->huart);
#endif
}

// uart2~5 interrupt
__attribute__((isr)) void UART2_5_IRQHandler(void)
{
#if MICROPY_HW_EN_UART2
    if(MP_STATE_VM(pyb_uart_obj_all)[2] && MP_STATE_VM(pyb_uart_obj_all)[2]->is_enabled){
        HAL_UART_IRQHandler(&MP_STATE_VM(pyb_uart_obj_all)[2]->huart);
    }
#endif
#if MICROPY_HW_EN_UART3
    if(MP_STATE_VM(pyb_uart_obj_all)[3] && MP_STATE_VM(pyb_uart_obj_all)[3]->is_enabled){
       HAL_UART_IRQHandler(&MP_STATE_VM(pyb_uart_obj_all)[3]->huart);
    }
#endif
#if MICROPY_HW_EN_UART4
    if(MP_STATE_VM(pyb_uart_obj_all)[4] && MP_STATE_VM(pyb_uart_obj_all)[4]->is_enabled){
        HAL_UART_IRQHandler(&MP_STATE_VM(pyb_uart_obj_all)[4]->huart);
    }
#endif
#if MICROPY_HW_EN_UART5
    if(MP_STATE_VM(pyb_uart_obj_all)[2] && MP_STATE_VM(pyb_uart_obj_all)[2]->is_enabled){
        HAL_UART_IRQHandler(&MP_STATE_VM(pyb_uart_obj_all)[5]->huart);
    }
#endif
}

// timer0-5 interrtupt
__attribute__((isr)) void TIM0_5_IRQHandler(void)
{
#if MICROPY_HW_EN_TIMER0
    if(MP_STATE_VM(timer_obj_all)[0] && MP_STATE_VM(timer_obj_all)[0]->is_enabled){
        HAL_TIM_IRQHandler(&MP_STATE_VM(timer_obj_all)[0]->htim);
    }
#endif
#if MICROPY_HW_EN_TIMER1
    if(MP_STATE_VM(timer_obj_all)[1] && MP_STATE_VM(timer_obj_all)[1]->is_enabled){
        HAL_TIM_IRQHandler(&MP_STATE_VM(timer_obj_all)[1]->htim);
    }
#endif
#if MICROPY_HW_EN_TIMER2
    if(MP_STATE_VM(timer_obj_all)[2] && MP_STATE_VM(timer_obj_all)[2]->is_enabled){
        HAL_TIM_IRQHandler(&MP_STATE_VM(timer_obj_all)[2]->htim);
    }
#endif
#if MICROPY_HW_EN_TIMER3
    if(MP_STATE_VM(timer_obj_all)[3] && MP_STATE_VM(timer_obj_all)[3]->is_enabled){
        HAL_TIM_IRQHandler(&MP_STATE_VM(timer_obj_all)[3]->htim);
    }
#endif
#if MICROPY_HW_EN_TIMER4
    if(MP_STATE_VM(timer_obj_all)[4] && MP_STATE_VM(timer_obj_all)[4]->is_enabled){
        HAL_TIM_IRQHandler(&MP_STATE_VM(timer_obj_all)[4]->htim);
    }
#endif
#if MICROPY_HW_EN_TIMER5
    if(MP_STATE_VM(timer_obj_all)[5] && MP_STATE_VM(timer_obj_all)[5]->is_enabled){
        HAL_TIM_IRQHandler(&MP_STATE_VM(timer_obj_all)[5]->htim);
    }
#endif
    //printf("tim isr exit.\n");
}

// pwm interrupt(not used)
__attribute__((isr)) void PWM_IRQHandler(void)
{
    //printf("IF:%x\n", PWM->IF);
	//printf("CH4CR3 IF:%x\n", PWM->CH4CR3);
    
    SET_BIT(PWM->IF, PWM_IF_CFLIF|PWM_IF_CRLIF);              // cap0(PWM0)
	SET_BIT(PWM->CH4CR3, PWM_CH4CR3_CFLIF|PWM_CH4CR3_CRLIF);  // cap1(pwm4)
    
}

// PWM CAP0(PWM0), CAP1(PWM4) DMA interrupt(not used)
__attribute__((isr)) void DMA_Channel4_7_IRQHandler(void)
{
	//printf("touch\n");
	//HAL_DMA_IRQHandler(&hdma);
}

// rtc alarm interrupt
__attribute__((isr)) void PMU_IRQHandler(void)
{
    HAL_PMU_IRQHandler(&MP_STATE_VM(rtc_obj)->hpmu);
}

// gpio exti interrupt
extern void GPIO_EXTI_Callback(uint32_t port_nr, uint32_t pin_nr);

static inline void _gpio_irq_handler(GPIO_TypeDef* port, int pincnt)
{
    uint32_t port_nr = ((uint32_t)port - GPIOA_BASE) / (GPIOB_BASE - GPIOA_BASE);
    //printf("exti callback. port_nr:%d\n", port_nr);
	for(int i = 0; i < pincnt; i++){
		if(port->MIS & (1<<i)){
            SET_BIT(port->IC, (1<<i));
            GPIO_EXTI_Callback(port_nr, i);
			//HAL_GPIO_EXTI_IRQHandler(port, 1<<i);
		}
	}
}

__attribute__((isr)) void GPIOA_IRQHandler(void)
{
    _gpio_irq_handler(GPIOA, 16);  // 最多16个GPIO
}

__attribute__((isr)) void GPIOB_IRQHandler(void)
{
    _gpio_irq_handler(GPIOB, 32); // 最多32个GPIO
}


#if 0
extern void RSA_F_IRQHandler(void);
extern void CRYPTION_IRQHandler(void);

__attribute__((isr)) void GPSEC_IRQHandler(void)
{
    CRYPTION_IRQHandler();
}

__attribute__((isr)) void RSA_IRQHandler(void)
{
    RSA_F_IRQHandler();
}
#endif


// SPI Interrupt 
__attribute__((isr)) void SPI_LS_IRQHandler(void)
{
    if(MP_STATE_VM(spi_obj)){
        HAL_SPI_IRQHandler(&MP_STATE_VM(spi_obj)->hspi);
    }
}

// SPI DMA Interrupt(read or write operation at a stage)
__attribute__((isr)) void DMA_Channel0_IRQHandler(void)
{
    if(MP_STATE_VM(spi_obj)){
        HAL_DMA_IRQHandler(&MP_STATE_VM(spi_obj)->hdma);
    }
}
